package org.luxor.commons.core.utils;

import java.math.BigDecimal;
import java.text.DecimalFormat;

/**
 * 简单算术计算
 *
 * @author admin @date 2019/9/15 15:37 @version 0.0.1
 */
public class BigDecimalUtils {

    /**
     * 相加
     */
    public static Double add(Double d1, Double d2) {
        BigDecimal bd1 = BigDecimal.valueOf(d1.doubleValue());
        BigDecimal bd2 = BigDecimal.valueOf(d2.doubleValue());
        return Double.valueOf(bd1.add(bd2).doubleValue());
    }

    /**
     * 相减
     */
    public static Double sub(Double d1, Double d2) {
        BigDecimal bd1 = BigDecimal.valueOf(d1.doubleValue());
        BigDecimal bd2 = BigDecimal.valueOf(d2.doubleValue());
        return Double.valueOf(bd1.subtract(bd2).doubleValue());
    }

    /**
     * 相乘
     */
    public static Double mul(Double d1, Double d2) {
        BigDecimal bd1 = BigDecimal.valueOf(d1.doubleValue());
        BigDecimal bd2 = BigDecimal.valueOf(d2.doubleValue());
        return Double.valueOf(bd1.multiply(bd2).doubleValue());
    }

    /**
     * 相除
     */
    public static Double div(Double d1, Double d2) {
        BigDecimal bd1 = BigDecimal.valueOf(d1.doubleValue());
        BigDecimal bd2 = BigDecimal.valueOf(d2.doubleValue());
        return Double.valueOf(bd1.divide(bd2).doubleValue());
    }


    /**
     * 相除
     *
     * @param d1
     * @param d2
     * @param scale        保留小数位数
     * @param roundingMode 舍弃规则 通过BigDecimal获取
     *                     1、ROUND_CEILING
     *                     如果 BigDecimal 是正的，则做 ROUND_UP 操作；如果为负，则做 ROUND_DOWN 操作。
     *                     2、ROUND_DOWN
     *                     从不在舍弃(即截断)的小数之前增加数字。
     *                     3、ROUND_FLOOR
     *                     如果 BigDecimal 为正，则作 ROUND_UP ；如果为负，则作 ROUND_DOWN 。
     *                     4、ROUND_HALF_DOWN
     *                     若舍弃部分> .5，则作 ROUND_UP；否则，作 ROUND_DOWN 。
     *                     5、ROUND_HALF_EVEN
     *                     如果舍弃部分左边的数字为奇数，则作 ROUND_HALF_UP ；如果它为偶数，则作 ROUND_HALF_DOWN 。
     *                     6、ROUND_HALF_UP
     *                     若舍弃部分>=.5，则作 ROUND_UP ；否则，作 ROUND_DOWN 。
     *                     7、ROUND_UNNECESSARY
     *                     该“伪舍入模式”实际是指明所要求的操作必须是精确的，，因此不需要舍入操作。
     *                     8、ROUND_UP
     *                     总是在非 0 舍弃小数(即截断)之前增加数字。
     * @return
     */
    public static Double div(Double d1, Double d2, int scale, int roundingMode) {
        BigDecimal bd1 = BigDecimal.valueOf(d1.doubleValue());
        BigDecimal bd2 = BigDecimal.valueOf(d2.doubleValue());
        return Double.valueOf(bd1.divide(bd2, scale, roundingMode).doubleValue());
    }

    /**
     * 将分转成元
     *
     * @param amount
     * @return
     */
    public static double changeF2YToDouble(Integer amount) {
        if (null == amount) {
            return 0.0;
        }
        return div(Double.parseDouble(amount.toString()), 100.0);
    }


    /**
     * 保留零位小数
     */
    public static DecimalFormat df0 = new DecimalFormat("###");

    /**
     * 保留两位小数
     */
    public static DecimalFormat df2 = new DecimalFormat("###.00");

    /**
     * 保留四位小数
     */
    public static DecimalFormat df4 = new DecimalFormat("###.0000");

    /**
     * 将分转成元，保留两位小数
     *
     * @param amount
     * @return
     */
    public static double changeF2YToDouble(Double amount) {
        if (null == amount) {
            return 0.0;
        }
        return Double.parseDouble(df2.format(div(amount, 100.0)));
    }

    /**
     * 将分转成元，保留任意小数
     *
     * @param amount 价钱
     * @param df     保留位数
     * @return
     */
    public static double changeF2YToDouble(Double amount, DecimalFormat df) {
        if (null == amount) {
            return 0.0;
        }
        return Double.parseDouble(df.format(div(amount, 100.0)));
    }
}
